﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Dillon.CSV
{



    public class CSVWriter : IDisposable
    {
        readonly TextWriter writer;
        readonly CSVWriterSettings settings;
        readonly string stringSymbolEncode;
        readonly string stringSymbolStringValue;
        readonly char[] separators;
        public CSVWriter(TextWriter writer)
            : this(writer, CSVWriterSettings.Default)
        {

        }
        public CSVWriter(TextWriter writer, CSVWriterSettings settings)
        {
            this.writer = writer;
            this.settings = settings;
            this.stringSymbolEncode = new string(settings.StringSymbol, 2);
            this.stringSymbolStringValue = settings.StringSymbol.ToString();
            var sepatorList = new List<char> { '\r', '\n' };
            sepatorList.Add(settings.ColumnSeparator);
            this.separators = sepatorList.ToArray();
        }

        public void Dispose()
        {
            this.writer.Close();
        }
        public void Write(object[] values)
        {
            for (int i = 0; i < values.Length; i++)
            {
                var stringValue = this.ConvertToString(values[i]);
                this.Write(stringValue);
                if (i < values.Length - 1)
                {
                    this.writer.Write(this.settings.ColumnSeparator);
                }
            }
            this.writer.Write("\r\n");
        }

        protected string ConvertToString(object value)
        {
            if (value == null)
            {
                return string.Empty;
            }
            else
            {
                return (string)System.Convert.ChangeType(value, typeof(string));
            }
        }

        public void Write(string[] values)
        {
            for (int i = 0; i < values.Length; i++)
            {
                this.Write(values[i]);
                if (i < values.Length - 1)
                {
                    this.writer.Write(this.settings.ColumnSeparator);
                }
            }
            this.writer.Write("\r\n");
        }

        void Write(string value)
        {
            this.writer.Write(this.Encode(value));
        }

        protected virtual string Encode(string value)
        {
            if (value == null)
            {
                return string.Empty;
            }
            if (value.IndexOf(settings.StringSymbol) >= 0)
            {
                return string.Concat(settings.StringSymbol, value.Replace(this.stringSymbolStringValue, this.stringSymbolEncode), settings.StringSymbol);
            }
            else if (value.IndexOfAny(this.separators) >= 0)
            {
                return string.Concat(settings.StringSymbol, value, settings.StringSymbol);
            }
            return value;
        }


    }
}
